
package com.insigma.business.qrcode.soldier._provider.impl;

import com.alibaba.fastjson.JSON;
import cn.hutool.core.bean.*;
import com.insigma.business.qrcode.common.dto.SystemConfigDTO;
import com.insigma.business.qrcode.common.service.SequenceGenerator;
import com.insigma.business.qrcode.common._consumer.SystemConfigConsumer;
import com.insigma.business.qrcode.common.util.*;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.soldier._consumer.CompanyConsumer;
import com.insigma.business.qrcode.soldier._consumer.SoldierConsumer;
import com.insigma.business.qrcode.soldier._provider.BuriedPointProvider;
import com.insigma.business.qrcode.soldier._provider.SecurityProvider;
import com.insigma.business.qrcode.soldier.dto.*;
import com.insigma.business.qrcode.soldier.dto.gov.BaseProviderImpl;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.soldier.entity.CachedObjDO;
import com.insigma.business.qrcode.soldier.request.BuriedPointRequest;
import com.insigma.business.qrcode.soldier.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Date;


@Slf4j
@Service
@Component("securityProvider")
public class SecurityProviderImpl extends BaseProviderImpl implements SecurityProvider {

    @Autowired
    private CachedObjService cachedObjService;
    @Autowired
    @Qualifier(value = "mysqlCacheClient")
    private CacheClient cacheClient;
    @Autowired(required = false)
    private SequenceGenerator sequenceGenerator;
    @Autowired
    private SystemConfigConsumer systemConfigConsumer;
    @Autowired
    private SoldierConsumer soldierConsumer;
    @Autowired
    private CompanyConsumer companyConsumer;


    @Autowired
    private BuriedPointProvider buriedPointProvider;


    public static final String GRANT_TYPE = "authorization_code";


    private static String aliAppId;
    private static String merchantPrivateKey;
    private static String aliPayPublicKey;


    public void init() {
        SystemConfigDTO privateKey = systemConfigConsumer.getSystemConfigByName(CommonConstant.SYSTEM_CONFIG_ITEM_NAME_ALIPAY_LIFE_PRIVATE_KEY).getDto();
        SystemConfigDTO publicKey = systemConfigConsumer.getSystemConfigByName(CommonConstant.SYSTEM_CONFIG_ITEM_NAME_ALIPAY_LIFE_ALI_PUBLIC_KEY).getDto();
        SystemConfigDTO appId = systemConfigConsumer.getSystemConfigByName(CommonConstant.SYSTEM_CONFIG_ITEM_NAME_ALIPAY_LIFE_APP_ID).getDto();

        aliAppId = appId.getValue();
        merchantPrivateKey = privateKey.getValue();
        aliPayPublicKey = publicKey.getValue();
    }

    @Override
    public BaseResponse<LoggedInPersistentCommonUserDTO> getLoggedInPersistentCommonUser(final String token) {


        final BaseResponse<LoggedInPersistentCommonUserDTO> baseResponse = new BaseResponse<>();

        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {

            @Override
            public void check() {
                BizCheckUtil.checkNotBlank(token, "请求参数Token不能为空");
            }

            @Override
            public void executeService() {

                CachedObjDO cachedObjDO = getCachedObjDO(token);

                if (cachedObjDO == null) {
                    baseResponse.setDto(null);
                } else {
                    final LoggedInDTO loggedInDTO = JSON.parseObject(cachedObjDO.getCachedValue(), LoggedInDTO.class);
                    BizCheckUtil.checkNotNull(loggedInDTO, "根据Token获取Session出错");

                    final LoggedInPersistentCommonUserDTO loggedInGWDTO = new LoggedInPersistentCommonUserDTO();
                    BeanUtil.copyProperties(loggedInDTO.getLoggedInPersistentDTO(), loggedInGWDTO);
                    loggedInGWDTO.setAvatar(loggedInDTO.getLoggedInTransientInfoDTO().getAvatarRelativeUri());


                    final CompanyDTO companyDTO = companyConsumer.getCompanyByEmployeeId(loggedInGWDTO.getUserId()).getDto();
                    loggedInGWDTO.setOrgType(OrgTypeEnum.COMPANY.name());
                    if (companyDTO != null) {
                        loggedInGWDTO.setOrgId(companyDTO.getId());
                    }

                    baseResponse.setDto(loggedInGWDTO);
                }
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.GET_LOGGED_IN_PERSISTENT_COMMON_USER_BY_TOKEN;
            }
        });

        return baseResponse;
    }

    @Override
    public BaseResponse<LoggedInPersistentMerchantUserDTO> getLoggedInPersistentMerchantUser(String token) {

        BizCheckUtil.checkNotBlank(token, "请求参数Token不能为空");

        CachedObjDO cachedObjDO = getCachedObjDO(token);

        if (cachedObjDO != null) {
            final MerchantLoggedInDTO loggedInDTO = JSON.parseObject(cachedObjDO.getCachedValue(), MerchantLoggedInDTO.class);
            BizCheckUtil.checkNotNull(loggedInDTO, "根据Token获取Session出错");

            final LoggedInPersistentMerchantUserDTO loggedInGWDTO = new LoggedInPersistentMerchantUserDTO();
            BeanUtil.copyProperties(loggedInDTO.getLoggedInPersistentDTO(), loggedInGWDTO);

            return ResponseUtils.buildSuccessResponse(loggedInGWDTO);
        }
        return ResponseUtils.buildSuccessResponse(null);
    }

    private CachedObjDO getCachedObjDO(String token) {
        CachedObjDO cachedObjDO = cachedObjService.getByKey(CommonConstant.CACHE_KEY_PREFIX_SESSION + token);
        if (cachedObjDO != null) {
            if (cachedObjDO.getExpiredDatetime().compareTo(Date.from(Instant.now())) <= 0) {

                cachedObjService.deleteByCacheKey(CommonConstant.CACHE_KEY_PREFIX_SESSION + token, cachedObjDO.getCreatorType(), cachedObjDO.getCreatorId());
                cachedObjDO = null;
            } else {
                cachedObjService.refreshTimeout(cachedObjDO);
            }
        }
        return cachedObjDO;
    }


    @Override
    public BaseResponse<LoggedInPersistentGovEmployeeDTO> getLoggedInPersistentGovEmployee(final String token) {


        final BaseResponse<LoggedInPersistentGovEmployeeDTO> baseResponse = new BaseResponse<>();

        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {

            @Override
            public void check() {
                BizCheckUtil.checkNotBlank(token, "请求参数Token不能为空");
            }

            @Override
            public void executeService() {
                CachedObjDO cachedObjDO = getCachedObjDO(token);

                if (cachedObjDO == null) {
                    baseResponse.setDto(null);
                } else {
                    final LoggedInDTO loggedInDTO = JSON.parseObject(cachedObjDO.getCachedValue(), LoggedInDTO.class);
                    BizCheckUtil.checkNotNull(loggedInDTO, "根据Token获取Session出错");

                    final LoggedInPersistentGovEmployeeDTO loggedInGWDTO = new LoggedInPersistentGovEmployeeDTO();
                    BeanUtil.copyProperties(loggedInDTO.getLoggedInPersistentDTO(), loggedInGWDTO);
                    loggedInGWDTO.setRoleCode(loggedInDTO.getLoggedInTransientInfoDTO().getRoles());
                    loggedInGWDTO.setResourceCodes(loggedInDTO.getLoggedInTransientInfoDTO().getResourceCodes());
                    baseResponse.setDto(loggedInGWDTO);
                }
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.GET_LOGGED_IN_PERSISTENT_GOV_EMPLOYEE_BY_TOKEN;
            }
        });

        return baseResponse;
    }


    @Override
    public BaseResponse<LoggedInPersistentSoldierDTO> getLoggedInSoldierPersistentSoldier(final String token) {


        final BaseResponse<LoggedInPersistentSoldierDTO> baseResponse = new BaseResponse<>();

        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {

            @Override
            public void check() {
                BizCheckUtil.checkNotBlank(token, "请求参数Token不能为空");
            }

            @Override
            public void executeService() {
                CachedObjDO cachedObjDO = getCachedObjDO(token);

                if (cachedObjDO == null) {
                    baseResponse.setDto(null);
                } else {
                    final LoggedInDTO loggedInDTO = JSON.parseObject(cachedObjDO.getCachedValue(), LoggedInDTO.class);
                    BizCheckUtil.checkNotNull(loggedInDTO, "根据Token获取Session出错");

                    final LoggedInPersistentSoldierDTO loggedInGWDTO = new LoggedInPersistentSoldierDTO();
                    BeanUtil.copyProperties(loggedInDTO.getLoggedInPersistentDTO(), loggedInGWDTO);
                    loggedInGWDTO.setRealName(loggedInDTO.getLoggedInTransientInfoDTO().getName());
                    loggedInGWDTO.setAvatar(loggedInDTO.getLoggedInTransientInfoDTO().getAvatarRelativeUri());
                    baseResponse.setDto(loggedInGWDTO);

                    BuriedPointRequest soldier = new BuriedPointRequest(loggedInGWDTO.getUserId(), "", "SOLDIER", true);
                    buriedPointProvider.setBuriedPointOfSetByDay(soldier);
                    buriedPointProvider.asyncSetBuriedPointOfHashByDayOfAdminCode(soldier);
                }
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.GET_LOGGED_IN_PERSISTENT_SOLDIER_BY_TOKEN;
            }
        });

        return baseResponse;
    }


    @Override
    public BaseResponse<String> getClientRedirectUrlByAlipayLifeH5Callback(final AlipayOAuth2RedirectDealRequest alipayOAuth2RedirectDealRequest) {


//        final BaseResponse<String> baseResponse = new BaseResponse<>();
//        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
//            @Override
//            public void check() {
//
//                if (aliAppId == null) {
//                    init();
//                }
//
//                BizCheckUtil.checkNotNull(alipayOAuth2RedirectDealRequest, "请求参数不能为空");
//                BizCheckUtil.checkNotBlank(alipayOAuth2RedirectDealRequest.getApp_id(), "appId不能为空");
//                BizCheckUtil.checkNotBlank(alipayOAuth2RedirectDealRequest.getAuth_code(), "authCode不能为空");
//                BizCheckUtil.checkNotBlank(alipayOAuth2RedirectDealRequest.getState(), "csrf的state不能为空");
//
//                final SystemConfigDTO appIdSystemConfigDTO = systemConfigConsumer.getSystemConfigByName(CommonConstant.SYSTEM_CONFIG_ITEM_NAME_ALIPAY_LIFE_APP_ID).getDto();
//                BizCheckUtil.checkNotNull(appIdSystemConfigDTO, "支付宝生活号APPID未初始化");
//                BizCheckUtil.checkNotBlank(appIdSystemConfigDTO.getValue(), "支付宝生活号授权APPID初始化值错误");
//                BizCheckUtil.checkEqual(appIdSystemConfigDTO.getValue(), alipayOAuth2RedirectDealRequest.getApp_id(), "支付宝回传appid非法");
//            }
//
//            @Override
//            public void executeService() {
//                String alipayUserId = null;
//                AlipayUserInfoShareResponse userInfo = null;
//                try {
//
//                    AlipaySystemOauthTokenRequest oauthTokenRequest = new AlipaySystemOauthTokenRequest();
//                    oauthTokenRequest.setCode(alipayOAuth2RedirectDealRequest.getAuth_code());
//                    oauthTokenRequest.setGrantType(GRANT_TYPE);
//
//                    AlipayClient alipayClient = AlipayAPIClientFactory.getAlipayClient(aliAppId, merchantPrivateKey, aliPayPublicKey);
//                    com.alipay.api.response.AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient
//                            .execute(oauthTokenRequest);
//
//                    log.info("获取支付宝信息，userId:{}", oauthTokenResponse.getUserId());
//                    alipayUserId = oauthTokenResponse.getUserId();
//
//                    if (oauthTokenResponse.isSuccess()) {
//
//                        AlipayUserInfoShareRequest userInfoShareRequest = new AlipayUserInfoShareRequest();
//                        AlipayUserInfoShareResponse userInfoShareResponse = alipayClient
//                                .execute(userInfoShareRequest, oauthTokenResponse.getAccessToken());
//
//                        if (null != userInfoShareResponse && userInfoShareResponse.isSuccess()) {
//                            log.info("获取支付宝用户信息:{}", userInfoShareResponse.getBody());
//                            userInfo = userInfoShareResponse;
//                        } else {
//                            log.error("获取支付宝信息失败，request:{}", alipayOAuth2RedirectDealRequest);
//                            throw new BizException(ErrorCodeEnum.COMMON_INNER_ERROR, "授权失败");
//                        }
//                    } else {
//                        log.error("authCode换取authToken失败, request:{}", alipayOAuth2RedirectDealRequest);
//                        throw new BizException(ErrorCodeEnum.COMMON_INNER_ERROR, "授权失败");
//                    }
//                } catch (Exception e) {
//                    ExceptionUtil.caught(log, e);
//                }
//
//                final SoldierGetByOuterSystemRequest soldierGetByOuterSystemRequest = new SoldierGetByOuterSystemRequest();
//                soldierGetByOuterSystemRequest.setOuterSysType(1);
//                soldierGetByOuterSystemRequest.setOuterSysAccountId(alipayUserId);
//
//                SoldierDTO soldierDTO = soldierConsumer.getSoldierOfOuterSysSrc(soldierGetByOuterSystemRequest).getDto();
//                if (soldierDTO == null) {
//
//                    if (userInfo != null && BizCheckUtils.checkMobile(userInfo.getUserName())) {
//                        log.error("新用户未实名:{}", JSON.toJSONString(userInfo));
//
//                    }
//
//                    final SoldierRegisterByOuterSystemRequest registerByOuterSystemRequest = new SoldierRegisterByOuterSystemRequest();
//                    registerByOuterSystemRequest.setOuterSysType(1);
//                    registerByOuterSystemRequest.setOuterSysAccountId(alipayUserId);
//                    registerByOuterSystemRequest.setLastLoginDatetime(new Date());
//                    registerByOuterSystemRequest.setOuterSysNickName(userInfo.getUserName());
//                    registerByOuterSystemRequest.setOuterSysAvatarUrl(userInfo.getAvatar());
//                    registerByOuterSystemRequest.setOuterSysProvince(userInfo.getProvince());
//                    registerByOuterSystemRequest.setOuterSysCity(userInfo.getCity());
//                    registerByOuterSystemRequest.setOuterSysGender(userInfo.getGender());
//                    registerByOuterSystemRequest.setOuterStatus(userInfo.getCode());
//                    registerByOuterSystemRequest.setOuterSysCertNo(userInfo.getCertNo());
//                    registerByOuterSystemRequest.setOuterSysIsCertified(userInfo.getIsCertified());
//                    registerByOuterSystemRequest.setOuterSysMobile(userInfo.getMobile());
//
//
//                    soldierDTO = soldierConsumer.registerByOuterSys(registerByOuterSystemRequest).getDto();
//
//                } else {
//
//
//                    if (BizCheckUtils.checkMobile(soldierDTO.getOuterAccount().getOuterSysNickName())
//                            || "0000".equals(soldierDTO.getOuterAccount().getOuterSysCertNo())) {
//                        if (userInfo != null && !BizCheckUtils.checkMobile(userInfo.getUserName())) {
//                            log.error("刷新姓名为手机的情况，soliderid:{}, mobile:{}, realName", soldierDTO.getId(),
//                                    soldierDTO.getOuterAccount().getOuterSysNickName(), userInfo.getUserName());
//                            soldierConsumer.updateBaseInfo(soldierDTO.getId(), userInfo.getUserName(), userInfo.getCertNo(), userInfo.getIsCertified(), userInfo.getMobile());
//
//
//                        } else {
//                            log.error("老用户未实名:{}", JSON.toJSONString(userInfo));
//
//                        }
//                    } else if (Strings.isBlank(soldierDTO.getOuterAccount().getOuterSysCertNo())) {
//                        log.info("更新身份证为空的情况:{}", JSON.toJSONString(soldierDTO.getOuterAccount()));
//                        soldierConsumer.updateBaseInfo(soldierDTO.getId(), userInfo.getUserName(), userInfo.getCertNo(), userInfo.getIsCertified(), userInfo.getMobile());
//                    }
//                }
//
//
//                final LoggedInDTO loggedInDTO = buildLoggedInSoldierDTO(soldierDTO);
//                storeLoggedInSession(TerminalAppTypeEnum.ALIPAY_H5.name() + "_" + UserTypeEnum.SOLDIER, loggedInDTO, UserTypeEnum.SOLDIER.name(),
//                        RpcContextUtil.getSessionBasis() == null ? null : RpcContextUtil.getSessionBasis().getVisitorId());
//
//                final SystemConfigDTO frontLoginUrlSystemConfigDTO = systemConfigConsumer.getSystemConfigByName(CommonConstant.SYSTEM_CONFIG_ITEM_NAME_ALIPAY_LIFE_FRONT_LOGIN_INDEX_URL).getDto();
//                BizCheckUtil.checkNotNull(frontLoginUrlSystemConfigDTO, "支付宝生活号后端智能登录或注册后回调到前端的URL未初始化");
//                BizCheckUtil.checkNotBlank(frontLoginUrlSystemConfigDTO.getValue(), "支付宝生活号后端智能登录或注册后回调到前端的URL初始化值错误");
//
//                baseResponse.setDto(frontLoginUrlSystemConfigDTO.getValue() + loggedInDTO.getLoggedInPersistentDTO().getToken());
//            }
//
//            @Override
//            public ScenarioCodeEnum getScenarioEnum() {
//                return ScenarioCodeEnum.ALIPAY_LIFE_REGISTER_OR_LOGIN;
//            }
//        });
//        return baseResponse;
        return null;
    }


    private MerchantLoggedInDTO buildLoggedInMerchantUserDTO(final SoldierDTO userDTO, String alipayUserId) {

//        final String loggedInToken = IDGenerator.genUUID() + userDTO.getId().substring(14, 16);
//        final MerchantLoggedInDTO loggedInDTO = new MerchantLoggedInDTO();
//        final MerchantLoggedInPersistentDTO persistentDTO = new MerchantLoggedInPersistentDTO();
//        persistentDTO.setToken(loggedInToken);
//        persistentDTO.setMobile(userDTO.getMobile());
//        persistentDTO.setAliUserId(alipayUserId);
//        persistentDTO.setUserId(userDTO.getId());
//        loggedInDTO.setLoggedInPersistentDTO(persistentDTO);
//
//        final MerchantLoggedInTransientInfoDTO transientInfoDTO = new MerchantLoggedInTransientInfoDTO();
//        transientInfoDTO.setStatus(userDTO.getStatus());
//        transientInfoDTO.setAvatarRelativeUri(userDTO.getAvatarRelativeUri());
//
//        loggedInDTO.setLoggedInTransientInfoDTO(transientInfoDTO);
//
//        return loggedInDTO;
        return null;
    }


    private void storeLoggedInMerchantUserSession(final String systemType, final MerchantLoggedInDTO buildLoggedInMemberDTO, final String creatorType, final String creatorId) {
//        final CachedObjDO cachedObj = new CachedObjDO();
//        cachedObj.setId(sequenceGenerator.genKey(SequenceNameConstant.CACHED_OBJ_ID));
//        cachedObj.setCachedKey(CommonConstant.CACHE_KEY_PREFIX_SESSION + buildLoggedInMemberDTO.getLoggedInPersistentDTO().getToken());
//        cachedObj.setCachedValue(JSON.toJSONString(buildLoggedInMemberDTO));
//        cachedObj.setSystemType(systemType);
//        cachedObj.setTimeoutSecond(7 * 24 * 60 * 60);
//        cachedObj.setRemark(systemType + "端用户登录成功");
//        cachedObj.setCreatorType(creatorType);
//        cachedObj.setCreatorId(creatorId);
//
//        cacheClient.put(cachedObj);
    }

    private LoggedInDTO buildLoggedInSoldierDTO(final SoldierDTO persistentMemberDTO) {

//        final String loggedInToken = IDGenerator.genUUID() + persistentMemberDTO.getId().substring(14, 16);
//
//        final LoggedInDTO loggedInDTO = new LoggedInDTO();
//
//        final LoggedInPersistentDTO persistentDTO = new LoggedInPersistentDTO();
//        persistentDTO.setToken(loggedInToken);
//        persistentDTO.setMobile(persistentMemberDTO.getMobile());
//        persistentDTO.setUserId(persistentMemberDTO.getId());
//
//
//        loggedInDTO.setLoggedInPersistentDTO(persistentDTO);
//
//        final LoggedInTransientInfoDTO transientInfoDTO = new LoggedInTransientInfoDTO();
//
//        transientInfoDTO.setName(persistentMemberDTO.getName());
//        transientInfoDTO.setStatus(persistentMemberDTO.getStatus());
//        transientInfoDTO.setAvatarRelativeUri(persistentMemberDTO.getAvatarRelativeUri());
//
//        loggedInDTO.setLoggedInTransientInfoDTO(transientInfoDTO);
//
//        return loggedInDTO;
        return null;
    }


    private void storeLoggedInSession(final String systemType, final LoggedInDTO buildLoggedInMemberDTO, final String creatorType, final String creatorId) {
        final CachedObjDO cachedObj = new CachedObjDO();
        cachedObj.setId(sequenceGenerator.genKey("CACHED_OBJ_ID"));
        cachedObj.setCachedKey(CommonConstant.CACHE_KEY_PREFIX_SESSION + buildLoggedInMemberDTO.getLoggedInPersistentDTO().getToken());
        cachedObj.setCachedValue(JSON.toJSONString(buildLoggedInMemberDTO));
        cachedObj.setSystemType(systemType);
        cachedObj.setTimeoutSecond(7 * 24 * 60 * 60);
        cachedObj.setRemark(systemType + "端用户登录成功，Session有效时间7天");
        cachedObj.setCreatorType(creatorType);
        cachedObj.setCreatorId(creatorId);

        cacheClient.put(cachedObj);
    }
}
